GFile *remote_cache_dir;
GFile *config_file;
+ GFile *transaction_lock_path;
+
GMutex cache_lock;
GPtrArray *cached_meta_indexes;
GPtrArray *cached_content_indexes;
g_clear_object (&self->uncompressed_objects_dir);
g_clear_object (&self->remote_cache_dir);
g_clear_object (&self->config_file);
+
+ g_clear_object (&self->transaction_lock_path);
+
if (self->loose_object_devino_hash)
g_hash_table_destroy (self->loose_object_devino_hash);
if (self->updated_uncompressed_dirs)
gboolean
ostree_repo_prepare_transaction (OstreeRepo *self,
gboolean enable_commit_hardlink_scan,
+ gboolean *out_transaction_resume,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
+ gboolean ret_transaction_resume = FALSE;
+ gs_free char *transaction_str = NULL;
g_return_val_if_fail (self->in_transaction == FALSE, FALSE);
+ if (self->transaction_lock_path == NULL)
+ self->transaction_lock_path = g_file_resolve_relative_path (self->repodir, "transaction");
+
+ if (g_file_query_file_type (self->transaction_lock_path, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) == G_FILE_TYPE_SYMBOLIC_LINK)
+ ret_transaction_resume = TRUE;
+ else
+ ret_transaction_resume = FALSE;
+
self->in_transaction = TRUE;
+ if (ret_transaction_resume)
+ {
+ if (!ot_gfile_ensure_unlinked (self->transaction_lock_path, cancellable, error))
+ goto out;
+ }
+ transaction_str = g_strdup_printf ("pid=%llu", (unsigned long long) getpid ());
+ if (!g_file_make_symbolic_link (self->transaction_lock_path, transaction_str,
+ cancellable, error))
+ goto out;
if (enable_commit_hardlink_scan)
{
}
ret = TRUE;
+ if (out_transaction_resume)
+ *out_transaction_resume = ret_transaction_resume;
out:
return ret;
}
g_return_val_if_fail (self->in_transaction == TRUE, FALSE);
- ret = TRUE;
- /* out: */
- self->in_transaction = FALSE;
+ if (!ot_gfile_ensure_unlinked (self->transaction_lock_path, cancellable, error))
+ goto out;
+
if (self->loose_object_devino_hash)
g_hash_table_remove_all (self->loose_object_devino_hash);
+ self->in_transaction = FALSE;
+ ret = TRUE;
+ out:
return ret;
}
gboolean ostree_repo_prepare_transaction (OstreeRepo *self,
gboolean enable_commit_hardlink_scan,
+ gboolean *out_transaction_resume,
GCancellable *cancellable,
GError **error);
GMainLoop *loop;
GCancellable *cancellable;
+ gboolean transaction_resuming;
volatile gint n_scanned_metadata;
guint outstanding_uri_requests;
if (!ostree_repo_has_object (pull_data->repo, objtype, tmp_checksum, &is_stored,
cancellable, error))
goto out;
-
+
if (!is_stored && !is_requested)
{
char *duped_checksum = g_strdup (tmp_checksum);
}
else if (is_stored)
{
- switch (objtype)
+ if (pull_data->transaction_resuming || is_requested)
{
- case OSTREE_OBJECT_TYPE_COMMIT:
- if (!scan_commit_object (pull_data, tmp_checksum, recursion_depth,
- pull_data->cancellable, error))
- goto out;
- break;
- case OSTREE_OBJECT_TYPE_DIR_META:
- break;
- case OSTREE_OBJECT_TYPE_DIR_TREE:
- if (!scan_dirtree_object (pull_data, tmp_checksum, recursion_depth,
- pull_data->cancellable, error))
- goto out;
- break;
- case OSTREE_OBJECT_TYPE_FILE:
- g_assert_not_reached ();
- break;
+ switch (objtype)
+ {
+ case OSTREE_OBJECT_TYPE_COMMIT:
+ if (!scan_commit_object (pull_data, tmp_checksum, recursion_depth,
+ pull_data->cancellable, error))
+ goto out;
+ break;
+ case OSTREE_OBJECT_TYPE_DIR_META:
+ break;
+ case OSTREE_OBJECT_TYPE_DIR_TREE:
+ if (!scan_dirtree_object (pull_data, tmp_checksum, recursion_depth,
+ pull_data->cancellable, error))
+ goto out;
+ break;
+ case OSTREE_OBJECT_TYPE_FILE:
+ g_assert_not_reached ();
+ break;
+ }
}
g_hash_table_insert (pull_data->scanned_metadata, g_variant_ref (object), object);
g_atomic_int_inc (&pull_data->n_scanned_metadata);
}
}
- if (!ostree_repo_prepare_transaction (pull_data->repo, FALSE, NULL, error))
+ if (!ostree_repo_prepare_transaction (pull_data->repo, FALSE, &pull_data->transaction_resuming,
+ cancellable, error))
goto out;
pull_data->metadata_objects_to_fetch = ot_waitable_queue_new ();
goto out;
}
- if (!ostree_repo_prepare_transaction (repo, TRUE, cancellable, error))
+ if (!ostree_repo_prepare_transaction (repo, TRUE, NULL, cancellable, error))
goto out;
in_transaction = TRUE;
int i;
GHashTableIter hash_iter;
gpointer key, value;
+ gboolean transaction_resuming = FALSE;
gs_unref_hashtable GHashTable *objects = NULL;
gs_unref_object GFile *src_f = NULL;
gs_unref_object GFile *src_repo_dir = NULL;
}
}
+ if (!ostree_repo_prepare_transaction (data->dest_repo, FALSE, &transaction_resuming,
+ cancellable, error))
+ goto out;
+
g_print ("Enumerating objects...\n");
source_objects = ostree_traverse_new_reachable ();
}
}
- if (!ostree_repo_prepare_transaction (data->dest_repo, FALSE, cancellable, error))
- goto out;
-
data->n_objects_to_check = g_hash_table_size (source_objects);
g_hash_table_iter_init (&hash_iter, source_objects);
while (g_hash_table_iter_next (&hash_iter, &key, &value))